﻿using System;
using System.Data;
using System.Linq;
using Npgsql;

namespace DBUtil.Provider.PostgreSql;

public class PostgreSqlBulkCopy
{
    private readonly NpgsqlConnection _connection;
    private readonly NpgsqlTransaction? _transaction;
    private readonly string _tableName;
    private bool _disposed;

    public PostgreSqlBulkCopy(NpgsqlConnection connection, string tableName, NpgsqlTransaction? transaction = null)
    {
        _connection = connection ?? throw new ArgumentNullException(nameof(connection));
        _transaction = transaction;
        _tableName = tableName ?? throw new ArgumentNullException(nameof(tableName));
    }

    /// <summary>
    /// 批量写入 DataTable
    /// </summary>
    public void WriteToServer(DataTable table)
    {
        if (table.Columns.Count == 0)
            throw new ArgumentException("DataTable 没有列");

        var columnList = string.Join(",", table.Columns.Cast<DataColumn>().Select(c => "\"" + c.ColumnName + "\""));
        var sql = $"COPY {_tableName} ({columnList}) FROM STDIN (FORMAT BINARY)";

        using (var writer = _connection.BeginBinaryImport(sql))
        {
            foreach (DataRow row in table.Rows)
            {
                writer.StartRow();
                foreach (DataColumn col in table.Columns)
                {
                    var value = row[col];
                    if (value == DBNull.Value)
                        writer.WriteNull();
                    else
                        writer.Write(value); // Npgsql 会自动推断类型
                }
            }
            writer.Complete();
        }
    }

    public void Dispose()
    {
        if (!_disposed)
        {
            // 注意：连接和事务的生命周期由外部管理，这里不做关闭
            _disposed = true;
        }
    }
}

